package com.yungam.imcs.controller.three_view;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import com.yungam.common.bean.energy.Energy;
import com.yungam.common.bean.equip.Equipment;
import com.yungam.common.bean.three_view.EquipShowConfig;
import com.yungam.common.response.RetDTO;
import com.yungam.common.service.EnergyService;
import com.yungam.common.service.EquipShowConfigService;
import com.yungam.common.service.EquipmentService;
import com.yungam.influxdb.service.ThreeViewService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Api(tags = "3D展示页面接口")
@RestController
@RequestMapping("/threeView")
public class ThreeViewController {

    @Resource
    private EquipmentService equipmentService;
    @Resource
    private EnergyService energyService;
    @Resource
    private ThreeViewService threeViewService;
    @Resource
    private EquipShowConfigService equipShowConfigService;

    @ApiOperation("获取页面数据")
    @GetMapping("/data")
    public RetDTO<?> getData() {
        List<Map<String, Object>> ans = Lists.newArrayList();

        List<Equipment> list = equipmentService.list(new QueryWrapper<Equipment>()
                .orderByAsc("equ_id")
                .select(Equipment.class, col -> !col.getProperty().equals("equImg")));

        // 获取能量值
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String str = now.format(df);
        String start = str + " 00:00:00", end = str + " 23:59:59";
        List<Energy> energyList = energyService.list(new QueryWrapper<Energy>().between("day", start, end));
        Map<Integer, Double> map = Maps.newHashMap();
        for (Energy energy : energyList) map.put(energy.getEquId(), energy.getNewValue());

        for (Equipment equipment : list) {
            Map<String, Object> cur = Maps.newHashMap();
            Integer equId = equipment.getEquId();
            cur.put("equId", equipment.getEquId());
            cur.put("equIp", equipment.getEquIp());
            cur.put("equName", equipment.getEquName());
            cur.put("current", String.format("%.2f", Math.random() * 100));
            cur.put("voltage", String.format("%.2f", Math.random() * 100));
            cur.put("energy", map.getOrDefault(equipment.getEquId(), 0d));
            if (equId.equals(90020) || equId.equals(90021)) {
                double temperature = Math.random() * 100, speed = Math.random() * 50;
                while (temperature < 80) {
                    temperature += 5;
                }
                cur.put("temperature", String.format("%.2f", temperature));
                cur.put("speed", String.format("%.2f", speed));
            } else if (equId.equals(90040)) {
                cur.put("diameter", String.format("%.2f", Math.random() * 10));
                cur.put("thickness", String.format("%.2f", Math.random() * 5));
            }
            ans.add(cur);
        }

        return RetDTO.data(ans);
    }

    @ApiOperation("获取页面真实数据")
    @GetMapping("/realData")
    public RetDTO<?> getRealData() {
        List<Equipment> list = equipmentService.list(new QueryWrapper<Equipment>()
                .orderByAsc("equ_id")
                .select(Equipment.class, col -> !col.getProperty().equals("equImg")));
        // 将设备id转为ip
        Map<Integer, String> transform = Maps.newHashMap();
        for (Equipment equip : list) transform.put(equip.getEquId(), equip.getEquIp());
        Map<String, Integer> transform2 = Maps.newHashMap();
        for (Equipment equip : list) transform2.put(equip.getEquIp(), equip.getEquId());

        // 获取能量值
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String str = now.format(df);
        String start = str + " 00:00:00", end = str + " 23:59:59";
        List<Energy> energyList = energyService.list(new QueryWrapper<Energy>().between("day", start, end));
        Map<Integer, Double> map = Maps.newHashMap();
        for (Energy energy : energyList) map.put(energy.getEquId(), energy.getNewValue());

        // 从 influxdb 查询实时值
        List<String> ipList = list.stream().map(Equipment::getEquIp).collect(Collectors.toList());
        List<FluxTable> tables = threeViewService.queryRealData(getParamIds(transform), ipList);

        Map<String, List<Map<String, Object>>> params = Maps.newHashMap();
        for (FluxTable table : tables) {
            List<FluxRecord> records = table.getRecords();
            for (FluxRecord record : records) {
                // ip
                String ip = String.valueOf(record.getValues().get("ip"));
                // name
                Object name = record.getValues().get("name");
                // value
                Object value = record.getValues().get("_value");
                if (Objects.isNull(value)) value = 0d;
                else {
                    Double d = (Double) value;
                    String format = String.format("%.2f", d);
                    value = Double.parseDouble(format);
                }
                List<Map<String, Object>> od = params.getOrDefault(ip, Lists.newArrayList());
                Map<String, Object> item = Maps.newHashMap();
                item.put("name", name);
                item.put("value", value);
                od.add(item);
                params.put(ip, od);
            }
        }
        // params 整合 energy
        for (Equipment equip : list) {
            String ip = equip.getEquIp();
            if (ip == null) continue;
            double energy = map.getOrDefault(transform2.get(ip), 0d);
            List<Map<String, Object>> od = params.getOrDefault(ip, Lists.newArrayList());
            Map<String, Object> item = Maps.newHashMap();
            item.put("name", "实时能量值");
            item.put("value", energy);
            od.add(item);
            params.put(ip, od);
        }

        // 整合数据
        Map<String, Map<String, Object>> ans = Maps.newHashMap();
        for (Equipment equip : list) {
            if (equip.getEquIp() == null) continue;
            Map<String, Object> cur = Maps.newHashMap();
            cur.put("equId", equip.getEquId());
            cur.put("equName", equip.getEquName());
            cur.put("params", params.get(equip.getEquIp()));
            ans.put(equip.getEquIp(), cur);
        }

        return RetDTO.data(ans);
    }

    /**
     * 获取各设备要查询的参数id
     */
    private Map<String, List<Integer>> getParamIds(Map<Integer, String> transform) {
        Map<String, List<Integer>> map = Maps.newHashMap();
        List<EquipShowConfig> list = equipShowConfigService.list();
        for (EquipShowConfig ec : list) {
            String ip = transform.get(ec.getEquId());
            List<Integer> od = map.getOrDefault(ip, Lists.newArrayList());
            od.add(ec.getCollectorItemId());
            map.put(ip, od);
        }

        return map;
    }
}
